package com.uivista.honeycomb;

import java.util.Iterator;

import com.wowza.wms.amf.AMFDataList;
import com.wowza.wms.amf.AMFDataObj;
import com.wowza.wms.application.IApplication;
import com.wowza.wms.application.IApplicationInstance;
import com.wowza.wms.application.IApplicationInstanceNotify;
import com.wowza.wms.application.IApplicationNotify;
import com.wowza.wms.client.IClient;
import com.wowza.wms.module.ModuleBase;
import com.wowza.wms.request.RequestFunction;
import com.wowza.wms.sharedobject.ISharedObject;
import com.wowza.wms.sharedobject.ISharedObjects;
import com.wowza.wms.sharedobject.SharedObject;
import com.wowza.wms.stream.IMediaStream;
import com.wowza.wms.stream.IMediaStreamActionNotify;
import com.wowza.wms.stream.IMediaStreamNotify;

public class Channel_20150312 extends ModuleBase {

	public static final String STREAMS_SONAME = "streamsSO";
	
	private IApplicationInstance appIn = null;
	
	IMediaStreamNotify mediaStreamListener = new MediaStreamListener();
	IMediaStreamActionNotify streamListener = new StreamListener();
	
	IApplicationInstance casterApp = null;
	IApplicationInstance caster2App = null;
	
	public void onAppStart(IApplicationInstance appInstance) {
		String fullname = appInstance.getApplication().getName() + "/"
				+ appInstance.getName();
		
		appIn = appInstance;
		
		getLogger().info("onAppStart: " + fullname);

		ISharedObjects sharedObjects = appInstance.getSharedObjects(false);

		ISharedObject streamsSO = new SharedObject("streamsSO");
		sharedObjects.put("streamsSO", streamsSO);
		streamsSO.lock();
		try {
			streamsSO.acquire();
		} catch (Exception localException) {
		} finally {
			streamsSO.unlock();
		}
		getLogger().info("onAppStart: create shared object: streamsSO");
		
		
		
		casterApp = appInstance.getVHost().getApplication("caster").getAppInstance("_definst_");
		caster2App = appInstance.getVHost().getApplication("caster2").getAppInstance("_definst_");
				
		//getLogger().info(casterApp);
		//getLogger().info(caster2App);
		
		//getLogger().info(appInstance.getApplication().getName());
		//getLogger().info(appInstance.getVHost().getApplicationNames());
		
		casterApp.addMediaStreamListener(mediaStreamListener);
		caster2App.addMediaStreamListener(mediaStreamListener);
		
		//casterApp.getStreams().addMediaStreamListener(new mediaStreamListener());
		
	}
	
	public void getStreamList(IClient client, RequestFunction function,
			AMFDataList params) {
		AMFDataObj amfObj = new AMFDataObj();
		
		try{
			Iterator iter = casterApp.getStreams().getStreams().iterator();
			
			getLogger().info(casterApp.getPublishStreamNames());
			getLogger().info(casterApp.getStreams().getStreams());
			
			while(iter.hasNext()){
				IMediaStream stream = (IMediaStream)iter.next();
				amfObj.put("label" + stream.getName(), stream.getName());				
			}
			
		}catch(Exception e){}
		
		try{
			Iterator iter = caster2App.getStreams().getStreams().iterator();
			getLogger().info(caster2App.getPublishStreamNames());
			getLogger().info(caster2App.getStreams().getStreams());
			while(iter.hasNext()){
				IMediaStream stream = (IMediaStream)iter.next();
				amfObj.put("label" + stream.getName(), stream.getName());				
			}
		}catch(Exception e){}
				
		sendResult(client, params, amfObj);
		
	}
	
	public void getSharedObjValues(IClient client, RequestFunction function, AMFDataList params)
	{		
		ISharedObjects sharedObjects = appIn.getSharedObjects();
		ISharedObject streamSO = sharedObjects.get("streamsSO");
		if(streamSO != null){
			streamSO.lock();
			try{
				
				getLogger().info("shared version : " + streamSO.getVersion());
				
				streamSO.deleteSlot("aaaaa");
				streamSO.purge(streamSO.getVersion() - 200);
				
				Iterator<String> iter = streamSO.getSlotNames().iterator();				
				getLogger().info(streamSO.getSlots());
				
				while(iter.hasNext()){
					String str = iter.next();
					getLogger().info(str + " -> " + streamSO.getProperty(str));
					/*
					if(streamSO.getProperty(str).equals("aa")){
						streamSO.deleteSlot(str);
						streamSO.purge(streamSO.getVersion() - 200);
					}
					*/
				}				
			}catch(Exception e){					
			}finally{
				streamSO.unlock();
			}				
		}
	}
	
	class MediaStreamListener implements IMediaStreamNotify
	{
		@Override
		public void onMediaStreamCreate(IMediaStream stream)
		{
			getLogger().info("#### stream create : " + stream.getName() + " " + stream.isPlay() + ", " + stream.isPublisherStream());
			stream.addClientListener(streamListener);
		}
		
		@Override
		public void onMediaStreamDestroy(IMediaStream stream) {
			// TODO Auto-generated method stub
			getLogger().info("#### stream destroy : " + stream.getName() + " " + stream.isPlay() + ", " + stream.isPublisherStream());
			stream.removeClientListener(streamListener);
			
			if(stream.isPlay() == false)
			{
				ISharedObjects sharedObjects = appIn.getSharedObjects();
				ISharedObject streamSO = sharedObjects.get("streamsSO");
				if(streamSO != null){
					streamSO.lock();
					try{
						streamSO.deleteSlot("c_" + stream.getName());
						streamSO.purge(streamSO.getVersion() - 200);
					}catch(Exception e){					
					}finally{
						streamSO.unlock();
					}				
				}
				
			}
			
		}				
	}

	class StreamListener implements IMediaStreamActionNotify
	{

		@Override
		public void onPause(IMediaStream stream, boolean isPause,
				double location) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onPlay(IMediaStream stream, String streamName,
				double playStart, double playLen, int playReset) {
			// TODO Auto-generated method stub
			getLogger().info("#### play : " + streamName);
		}

		@Override
		public void onPublish(IMediaStream stream, String streamName,
				boolean isRecord, boolean isAppend) {
			// TODO Auto-generated method stub
			getLogger().info("#### publish : " + streamName);
			
			ISharedObjects sharedObjects = appIn.getSharedObjects();
			ISharedObject streamSO = sharedObjects.get("streamsSO");
			if(streamSO != null){
				streamSO.lock();
				try{
					streamSO.setProperty("c_" + streamName, streamName);
				}catch(Exception e){					
				}finally{
					streamSO.unlock();
				}				
			}
			
		}

		@Override
		public void onSeek(IMediaStream stream, double location) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onStop(IMediaStream stream) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onUnPublish(IMediaStream stream, String streamName,
				boolean isRecord, boolean isAppend) {
			// TODO Auto-generated method stub
			
		}
		
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	public void onAppStop(IApplicationInstance appInstance) {
		String fullname = appInstance.getApplication().getName() + "/"
				+ appInstance.getName();
		
		appIn = null;
		
		getLogger().info("onAppStop: " + fullname);

		ISharedObjects sharedObjects = appInstance.getSharedObjects(false);
		ISharedObject streamsSO = sharedObjects.get("streamsSO");
		if (streamsSO != null) {
			getLogger().info("onAppStart: release shared object: streamsSO");
			streamsSO.lock();
			try {
				streamsSO.release();
			} catch (Exception localException) {
			} finally {
				streamsSO.unlock();
			}
		}
	}

	public void onConnect(IClient client, RequestFunction function,
			AMFDataList params) {
		//getLogger().info("onConnect: " + client.getClientId());
		//getLogger().info("username: " + params.getString(3));
		//getLogger().info("password: " + params.getString(4));
	}

	public void onConnectAccept(IClient client) {
		getLogger().info("onConnectAccept: " + client.getClientId());
	}

	public void onConnectReject(IClient client) {
		getLogger().info("onConnectReject: " + client.getClientId());
	}

	public void onDisconnect(IClient client) {
		//getLogger().info("onDisconnect: " + client.getClientId());

		ISharedObjects sharedObjects = client.getAppInstance()
				.getSharedObjects(false);
		ISharedObject streamsSO = sharedObjects.get("streamsSO");
		if (streamsSO != null) {
			streamsSO.lock();
			try {
				//getLogger().info("/n remove stream : c" + client.getClientId());
				streamsSO.deleteSlot("c" + client.getClientId());
				streamsSO.purge(streamsSO.getVersion() - 200);
			} catch (Exception localException) {
			} finally {
				streamsSO.unlock();
			}
		}
	}

	public void addChannel(IClient client, RequestFunction function,
			AMFDataList params) {
		//getLogger().info("/naddChannel");
		String streamName = params.getString(3);
		ISharedObjects sharedObjects = client.getAppInstance()
				.getSharedObjects(false);
		ISharedObject streamsSO = sharedObjects.get("streamsSO");
		if (streamsSO != null) {
			streamsSO.lock();
			try {
				//getLogger().info("/n add stream: c" + client.getClientId() + " , "+ streamName);
				streamsSO.setProperty("c" + client.getClientId(), streamName);
			} catch (Exception localException) {
			} finally {
				streamsSO.unlock();
			}
		}
	}

	public void deleteChannel(IClient client, RequestFunction function,
			AMFDataList params) {
		//getLogger().info("/ndeleteChannel");
		String streamName = params.getString(3);
		ISharedObjects sharedObjects = client.getAppInstance()
				.getSharedObjects(false);
		ISharedObject streamsSO = sharedObjects.get("streamsSO");
		if (streamsSO != null) {
			streamsSO.lock();
			try {
				//getLogger().info("/n remove stream : c" + client.getClientId() + " , "+ streamName);
				streamsSO.deleteSlot("c" + client.getClientId());
				streamsSO.purge(streamsSO.getVersion() - 200);
			} catch (Exception localException) {
			} finally {
				streamsSO.unlock();
			}
		}
	}
}